<template>
  <div
    v-if="!initializing"
    v-resize="resize"
    class="vc-component"
    :style="visual.parseStyle(currNode.currStyle)"
  >
    <div ref="chartDiv" class="vc-echarts-gauge" :style="style"></div>
  </div>
  <div
    v-else
    v-loading="true"
    element-loading-text=""
    style="min-height: 30px;"
    class="vc-component"
    :style="visual.parseStyle(currNode.currStyle)"
  ></div>
</template>

<script setup>
import { ref, onMounted, computed, inject, getCurrentInstance, markRaw, nextTick, onUnmounted } from 'vue';
import * as echarts from "echarts";
import visual from "@/visual/js/visual";
import EventHandler from "@/visual/js/event";
import JSON5 from 'json5';
import {parseColors} from "@/utils/color";
import tool from "@/utils/tool";

const props = defineProps({
  node: Object
});

const chartDiv = ref();
const currChart = ref(null);
const initializing = ref(true);
const currNode = ref(props.node);
const eventHandler = new EventHandler(
  inject('eventHandler', Function, true),
  getCurrentInstance(),
  currNode.value
);

const init = async(styleId) => {
  initializing.value = true;
  visual.initStyle(currNode.value, styleId);
  await nextTick(() => initializing.value = false);
};

const loadData = tool.debounce(async() => {
  if (!chartDiv.value) return;
  const compStyle = currNode.value.currCompStyle || {};
  const compData = currNode.value.compData || {};
  const defaultOption = JSON5.parse(compStyle['jsonOption'] || '{}');
  const dataList = (await visual.loadData(
    compData,
    eventHandler,
    getData(),
    currNode.value)).data || [];

  let seriesData = [];
  dataList.forEach(data => {
    seriesData.push({
      name: data['标签'],
      value: data['系列'],
    });
  });

  const option = {
    animation: compStyle['animation'] || false,
    color: parseColors(compStyle['colorScheme']),
    series: [
      {
        ...parseGauge(compStyle),
        data: seriesData
      }
    ]
  };

  await nextTick(() => {
    if (!chartDiv.value) return;
    if (currChart.value) currChart.value.dispose();
    currChart.value = markRaw(echarts.init(chartDiv.value));
    currChart.value.setOption(Object.assign({}, option, defaultOption));
  });
  resize();
});

const parseGauge = (compStyle) => {
  const result = { type: 'gauge' };

  result['radius'] = compStyle['series.radius'] || '75%';
  result['startAngle'] = compStyle['series.startAngle'] || 225;
  result['endAngle'] = compStyle['series.endAngle'] || -45;
  result['min'] = compStyle['series.minAngle'] || 0;
  result['max'] = compStyle['series.maxAngle'] || 100;
  result['splitNumber'] = compStyle['series.splitNumber'] || 10;

  result['axisLine'] = { show: !!compStyle['series.axisLine'] };
  result['axisLine'].lineStyle = {};
  result['axisLine'].lineStyle.width = compStyle['series.axisLine.width'] || 10;
  if (compStyle['series.axisLine.color']) {
    const colorList = [];
    const colors = compStyle['series.axisLine.color'].split(',');
    for (let i=0; i<colors.length; i=i+2) {
      colorList.push([colors[i], colors[i+1]]);
    }
    result['axisLine'].lineStyle.color = colorList;
  }

  result['progress'] = {
    show: !!compStyle['series.progress'],
    width: compStyle['series.progress.width'] || 10
  };

  result['splitLine'] = {
    show: !!compStyle['series.splitLine'],
    distance: compStyle['series.splitLine.distance'] || 10,
    lineStyle: {
      color: compStyle['series.splitLine.color'] || '#63677A'
    }
  };

  result['axisTick'] = {
    show: !!compStyle['series.axisTick'],
    distance: compStyle['series.axisTick.distance'] || 10,
    lineStyle: {
      color: compStyle['series.axisTick.color'] || '#63677A'
    },
  };

  result['axisLabel'] = { show: !!compStyle['series.axisLabel'] };
  result['pointer'] = {
    show: !!compStyle['series.pointer'],
    itemStyle: {
      color: compStyle['series.pointer.color'] || 'auto'
    }
  };
  result['title'] = {
    show: !!compStyle['series.title'],
    offsetCenter: (compStyle['series.title.offset'] || '0%,20%').split(',')
  };

  result['detail'] = {
    show: !!compStyle['series.detail'],
    formatter: compStyle['series.detail.formatter'],
    fontSize: compStyle['series.detail.fontSize'] || 14,
    color: compStyle['series.detail.color'] || 'inherit'
  };

  return result;
};

const style = computed(() => {
  const compStyle = currNode.value.currCompStyle || {};

  let result = '';
  result += visual.parseTpl('width: {value};', compStyle['width']);
  result += visual.parseTpl('height: {value};', compStyle['height']);
  return result;
});

const getData = () => {
  return { inputParam: currNode.value.inputParam || {} };
};

const changeStyle = (styleId) => {
  init(styleId);
};

const refresh = async() => {
  await init();
  loadData();
};

const resize = () => {
  try {
    currChart.value.resize();
  } catch (e) {
    console.log(e);
  }
};

onMounted(async() => {
  await init();
  loadData();
});

onUnmounted(() => {
  eventHandler.unregister();
});

defineExpose({ getData, changeStyle, refresh, loadData });
</script>